package org.wak.dialog.scumm
{
	import flash.display.DisplayObjectContainer;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.events.TimerEvent;
	import flash.filters.BitmapFilterQuality;
	import flash.filters.DropShadowFilter;
	import flash.text.TextField;
	import flash.text.TextFormat;
	import flash.text.TextFormatAlign;
	import flash.utils.Timer;
	import flash.utils.getTimer;
	
	import org.wak.character.display.AbstractCharacterDisplay;
	
	/**
	 * Class to display the dialog texts on screen for a certain amount of time. 
	 * 
	 */	
	public class DialogTextDisplay extends Sprite
	{
		// text field to display
		private var mField:TextField = null ;
		
		// time to show the text
		private var mTextTime:int = 1000 ;
		private var mContainer:DisplayObjectContainer = null ;
		
		// timer to show the text.
		private var mShowTimer:Timer = null ;
		
		// text formater
		private var mTextFormat:TextFormat = null ;
		
		// speaker character display.
		private var mSpeakerDisplay:AbstractCharacterDisplay = null ;
		
		// shadow filter
		private static var mShadow:DropShadowFilter = null ;
		
		// array of assigned DialogDisplay
		private static var mDialogDisplaysArray:Array = null ;
		
		// enable click end.
		private var mClickEndEnabled:Boolean = false ;
		
		private var mStartTime:uint = 0 ;
		
		/**
		 * Constructor 
		 * @param pText text to display.
		 * @param pTime time in milliseconds of for how long show the text 
		 * @param pContainer the container of this DialogTextDisplay
		 * @param pSpeakerDisplay the speaker's character display/
		 * @param pFont an optional font name to use.
		 * @param pFSize an optional font size to use.
		 * @param pColor an optional text color
		 * @param pBold optional bold the text font.
		 * 
		 */		 
		public function DialogTextDisplay(pText:String, pTime:int, pContainer:DisplayObjectContainer, pSpeakerDisplay:AbstractCharacterDisplay,
										  pFont:String = "acknowtt", pFSize:int = 14, pColor:uint = 0xFFFFFF, pBold:Boolean = true, pEmbedFont:Boolean = true)
		{
			super();
			//trace("DialogTextDisplay:")
			
			if(mDialogDisplaysArray == null)
				mDialogDisplaysArray = new Array();
			
			mSpeakerDisplay = pSpeakerDisplay; 
			//...
			mShadow = new DropShadowFilter(1, 31, 0x000000, 1, 6, 6, 4, BitmapFilterQuality.LOW, false, false, false);
			
			mTextFormat = new TextFormat();
			mTextFormat.align = TextFormatAlign.CENTER ;
			mTextFormat.font = pFont ;
			mTextFormat.size = pFSize ;
			mTextFormat.color = pColor ;
			mTextFormat.bold = pBold ;
			
			mField = new TextField();
			mField.defaultTextFormat = mTextFormat;
			mField.embedFonts = pEmbedFont ;
			//mField.autoSize = TextFieldAutoSize.CENTER ;
			mField.selectable = false ;
			
			//mField.border = true ;
			//mField.borderColor = 0xFFFFFF;
			
			mField.text = pText ;
			//mField.textColor = 0xFFFFFF ;
			
			mField.filters = [mShadow] ;
			
			this.addChild(mField);
			mTextTime = pTime ; 
			
			mShowTimer = new Timer(mTextTime,1);
			mShowTimer.addEventListener(TimerEvent.TIMER,OnTimeCompleted );
			
			mContainer = pContainer ;
			this.addEventListener(Event.ADDED_TO_STAGE, OnAddedToStage );
		}
		
		/**
		 * The AbstractCharacterDisplay who is talking.
		 * @return AbstractCharacterDisplay
		 * 
		 */		
		public function get speakerDisplay():AbstractCharacterDisplay 
		{
			return mSpeakerDisplay ;
		}
		
		/**
		 *  In the case you need to remove the DialogTextDisplay
		 * 	before the time expires, use this.
		 * 
		 */		
		public function Finish():void
		{
			trace("Finish:"+ mField.text)
			mShowTimer.stop();
			
			mShowTimer.removeEventListener(TimerEvent.TIMER,OnTimeCompleted );
			
			this.removeChild( mField);
			mField.visible = false ;
			mContainer.removeChild(this);
						
		}
		
		public override function set x(value:Number):void
		{
			super.x = value ;
			
			var fThirdOne:Number = mContainer.stage.stageWidth / 3 ;
			var fThirdTwo:Number = (mContainer.stage.stageWidth / 3) * 2 ;
			
			mField.wordWrap = true ;
			mField.width = (Math.round(fThirdOne) );
			
			super.x = value - (mField.width / 2);
			
			
			// text spill for the left side
			if(super.x < 0)
			{
				super.x = 0 ;
			}
			// text spill for the right side
			else if ((super.x + mField.width) > mContainer.stage.stageWidth)
			{
				var fDif:Number = (super.x + mField.width) - mContainer.stage.stageWidth ;
				super.x = super.x - Math.round(fDif) ;
			} 
		}
		
		public override function set y(value:Number):void
		{
			super.y = value ;
			
			var fHeight:Number = mContainer.stage.stageHeight / 4 ;
			
			mField.height = Math.round(fHeight) ;
			
			super.y = value - (mField.height / 2);
			
			// text spill for the upper border
			if(super.y < 0)
			{
				super.y = 0 ;
			}
			// text spill for the bottom border
			else if ((super.y + mField.height) > mContainer.stage.stageHeight)
			{
				var fDif:Number = (super.x + mField.height) - mContainer.stage.stageHeight ;
				super.y = super.y - Math.round(fDif) ;
			} 
		}
		
		/**
		 * Enable or the disable to end the text displaying 
		 * with a click. 
		 * @param value true or false.
		 * 
		 */		
		public function set clickEndEnabled(value:Boolean):void
		{
			mClickEndEnabled = value ;
		} 
		
		/**
		 * 
		 * @private 
		 * 
		 */		
		public function get clickEndEnabled():Boolean
		{
			return mClickEndEnabled ;
		}

		
		private function OnAddedToStage(event:Event):void
		{
			this.removeEventListener(Event.ADDED_TO_STAGE, OnAddedToStage );
			
			if(mSpeakerDisplay != null)
				var fPrevTextDisplay:DialogTextDisplay = mDialogDisplaysArray[mSpeakerDisplay.interactableId] as DialogTextDisplay;
			
			if( fPrevTextDisplay != null )
			{
				fPrevTextDisplay.Finish() ;
			}
			if(mSpeakerDisplay != null)
				mDialogDisplaysArray[mSpeakerDisplay.interactableId] = this ;
			
			if(clickEndEnabled)
				this.stage.addEventListener(MouseEvent.CLICK, OnMouseClick);
			
			mStartTime = getTimer();
			
			mShowTimer.start() ;
			
		}
		
		private function OnMouseClick(event:MouseEvent):void
		{
			var fEnd:uint = getTimer();
			if( (fEnd - mStartTime) > 100)
			{
				mShowTimer.stop();
				EndDisplay();
			}
		}
		
		private function OnTimeCompleted(event:TimerEvent):void
		{
			EndDisplay();
		}
		
		private function EndDisplay():void
		{
			mShowTimer.removeEventListener(TimerEvent.TIMER,OnTimeCompleted );
			if(mContainer.contains(this))
				mContainer.removeChild(this);
				
			if(mSpeakerDisplay != null)
				mDialogDisplaysArray[mSpeakerDisplay.interactableId] = null ;
			
			if(clickEndEnabled)
				mContainer.stage.removeEventListener(MouseEvent.CLICK, OnMouseClick);
			
			var fEvent:Event = new Event( Event.COMPLETE );
			this.dispatchEvent(fEvent);			
		}
		
		
		
		
	}
}